package com.spotmanger.project.modular.orgmanger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spotmanger.project.common.core.exception.BusinessException;
import com.spotmanger.project.common.core.exception.code.BaseResponseCode;
import com.spotmanger.project.modular.orgmanger.entity.SysDivisionEntity;
import com.spotmanger.project.modular.orgmanger.mapper.SysDivisionMapper;
import com.spotmanger.project.modular.orgmanger.service.SysDivisionService;
import com.spotmanger.project.modular.orgmanger.vo.DivisionRespNodeVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Service("sysDivisionService")
public class SysDivisionServiceImpl extends ServiceImpl<SysDivisionMapper, SysDivisionEntity> implements SysDivisionService {
    @Resource
    private SysDivisionMapper sysDivisionMapper;

    @Override
    public List<DivisionRespNodeVO> divisionTreeList(String divisionId, Boolean disabled) {
        List<SysDivisionEntity> list;
        if (StringUtils.isEmpty(divisionId)) {
            list = sysDivisionMapper.selectList(Wrappers.emptyWrapper());
        } else {
            SysDivisionEntity sysDivision = sysDivisionMapper.selectById(divisionId);
            if (sysDivision == null) {
                throw new BusinessException(BaseResponseCode.DATA_ERROR);
            }
            LambdaQueryWrapper<SysDivisionEntity> queryWrapper = Wrappers.<SysDivisionEntity>lambdaQuery().likeRight(SysDivisionEntity::getRelationCode, sysDivision.getRelationCode());
            List<Object> childIds = sysDivisionMapper.selectObjs(queryWrapper);
            list = sysDivisionMapper.selectList(Wrappers.<SysDivisionEntity>lambdaQuery().notIn(SysDivisionEntity::getId, childIds));
        }
        // 默认加一个顶级方便新增顶级部门
        DivisionRespNodeVO respNodeVO = new DivisionRespNodeVO();
        respNodeVO.setTitle("默认顶级部门");
        respNodeVO.setId("0");
        respNodeVO.setSpread(true);
        respNodeVO.setDisabled(disabled);
        respNodeVO.setChildren(getTree(list));
        List<DivisionRespNodeVO> result = new ArrayList<>();
        result.add(respNodeVO);
        return result;
    }
    private List<DivisionRespNodeVO> getTree(List<SysDivisionEntity> all) {
        List<DivisionRespNodeVO> list = new ArrayList<>();
        for (SysDivisionEntity sysDivision : all) {
            if ("0".equals(sysDivision.getPid())) {
                DivisionRespNodeVO deptTree = new DivisionRespNodeVO();
                BeanUtils.copyProperties(sysDivision, deptTree);
                deptTree.setTitle(sysDivision.getName());
                deptTree.setSpread(true);
                deptTree.setChildren(getChild(sysDivision.getId(), all));
                list.add(deptTree);
            }
        }
        return list;
    }

    private List<DivisionRespNodeVO> getChild(String id, List<SysDivisionEntity> all) {
        List<DivisionRespNodeVO> list = new ArrayList<>();
        for (SysDivisionEntity sysDivision : all) {
            if (sysDivision.getPid().equals(id)) {
                DivisionRespNodeVO deptTree = new DivisionRespNodeVO();
                BeanUtils.copyProperties(sysDivision, deptTree);
                deptTree.setTitle(sysDivision.getName());
                deptTree.setChildren(getChild(sysDivision.getId(), all));
                list.add(deptTree);
            }
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDivision(SysDivisionEntity vo) {

        SysDivisionEntity sysDivision = sysDivisionMapper.selectById(vo.getId());
        if (null == sysDivision) {
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        sysDivisionMapper.updateById(vo);
        //说明层级发生了变化
        if (!StringUtils.isEmpty(vo.getPid()) && !vo.getPid().equals(sysDivision.getPid())) {
            SysDivisionEntity parent = sysDivisionMapper.selectById(vo.getPid());
            if (!"0".equals(vo.getPid()) && null == parent) {
                throw new BusinessException(BaseResponseCode.DATA_ERROR);
            }
            SysDivisionEntity oldParent = sysDivisionMapper.selectById(sysDivision.getPid());
            String oldRelationCode;
            String newRelationCode;
            //根目录降到其他目录
            if ("0".equals(sysDivision.getPid())) {
                oldRelationCode = sysDivision.getDivisionNo();
                newRelationCode = parent.getRelationCode() + sysDivision.getDivisionNo();
            } else if ("0".equals(vo.getPid())) {
                // 其他目录升级到跟目录
                oldRelationCode = sysDivision.getRelationCode();
                newRelationCode = sysDivision.getDivisionNo();
            } else {
                oldRelationCode = oldParent.getRelationCode();
                newRelationCode = parent.getRelationCode();
            }
            LambdaQueryWrapper<SysDivisionEntity> wrapper = Wrappers.lambdaQuery();
            wrapper.likeLeft(SysDivisionEntity::getDivisionNo, sysDivision.getDivisionNo());
            List<SysDivisionEntity> list = sysDivisionMapper.selectList(wrapper);
            list.parallelStream().forEach(entity -> {
                String relationCode = entity.getRelationCode().replace(oldRelationCode, newRelationCode);
                entity.setRelationCode(relationCode);
                sysDivisionMapper.updateById(entity);
            });
        }
    }

    @Override
    public void addDivision(SysDivisionEntity vo) {
        String relationCode;
        String divisionCode = this.getNewDivisionCode();
        SysDivisionEntity parent = sysDivisionMapper.selectById(vo.getPid());
        if ("0".equals(vo.getPid())) {
            relationCode = divisionCode;
        } else if (null == parent) {
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        } else {
            relationCode = parent.getRelationCode() + vo.getDivisionNo();
        }
        vo.setRelationCode(relationCode);
        vo.setStatus(1);
        sysDivisionMapper.insert(vo);
    }

    //获取新的区划编码
    public String getNewDivisionCode() {
        LambdaQueryWrapper<SysDivisionEntity> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.select(SysDivisionEntity::getDivisionNo);
        //获取所有的divisionCode
        List<Object> divisionCodes = sysDivisionMapper.selectObjs(lambdaQueryWrapper);
        AtomicReference<Integer> maxDivisionCode = new AtomicReference<>(0);

        //遍历获取最大的DivisonCode
        divisionCodes.forEach(o -> {
            String str = String.valueOf(o);
            if (str.length() >= 6) {

                Integer one = Integer.parseInt(str.substring(str.length() - 4));
                if (one > maxDivisionCode.get()) {
                    maxDivisionCode.set(one);
                }
            }
        });

        return padRight(maxDivisionCode.get() + 1, 6, "0");
    }
    /**
     * 右补位，左对齐
     *
     * @param len    目标字符串长度
     * @param alexi  补位字符
     * @param oriStr 原字符串
     * @return 目标字符串
     * 以alexin 做为补位
     */
    public static String padRight(int oriStr, int len, String alexi) {
        StringBuilder str = new StringBuilder();
        int strlen = String.valueOf(oriStr).length();
        if (strlen < len) {
            for (int i = 0; i < len - strlen; i++) {
                str.append(alexi);
            }
        }
        str.append(oriStr);
        return "D" + str.toString();
    }
}
